/*
vue3 组件动态加载
Version: 3.0
Author: xuejianxin
Website: https://gitee.com/xuejianxinokok
Date:2020-10-09
*/


var xue = (function (exports) {

//console.log(exports);
	
let config={
	baseUrl : ''
}

async function loadAndParse(url, customOptions) {
    //使用浏览器内置fetch
    let response=await fetch( `${config.baseUrl}${url}` );
    let html= await response.text();
    //console.log(html);
    const parser = new DOMParser();
    const document = parser.parseFromString(html, 'text/html');
    const head = document.head;
    const template = head.querySelector('template');
    const style = head.querySelector('style');
    const script = head.querySelector('script');
    let o = {
        template,
        style,
        script,
        customOptions,
        url
    };
    return o;
}


async function getSettings({template, style, script, customOptions, url}) {
	let sourceID= url.startsWith("/")? url.substr(1):url;
	sourceID=sourceID.substr(0,sourceID.lastIndexOf("."));
	sourceID=sourceID.replace(/\//g, '-');
    let jsSourceUrl = ` \r\n //@ sourceURL=${sourceID}.js`
    let jsContent=script.textContent;
    
    
    //替换import 路径用于导入模块
    let importPath=`${window.location.origin}${config.baseUrl}${url}`;
    //console.log(url);
    importPath=importPath.substring(0,importPath.lastIndexOf("/"));
    
    const reg=/(import .* from.*)["'](.*)["']/gi;
    jsContent=jsContent.replace(reg,`$1 "${importPath}/$2"`);
    //console.log(  jsContent);
    
    let source = jsContent + jsSourceUrl;
    const jsFile = new Blob([source], {type: 'application/javascript'});
    const jsURL = URL.createObjectURL(jsFile);
    const compId = "comp-" + (jsURL.substring(jsURL.lastIndexOf("/") + 1));
    // https://webpack.js.org/api/module-methods/#import
    let module = await import(/* webpackIgnore: true */ jsURL );
    module.default._id = compId;
    
    if( Object.keys(customOptions).length>0){
       if(module.default.mixins) {
          // 存在混入追加到混入列表
          module.default.mixins.push(customOptions);// vue混入
       }else {
          // 否则添加混入
          module.default.mixins =[customOptions];// vue混入
       }
    }
    let vueConfig;
    if (style) {
        if(style.hasAttribute('scoped')){// 如果是局部样式scoped
           //sourceID="data-v-11";
           //获取所有样式表
           let ruleList=style.sheet.rules || style.sheet.cssRules;
           let compStyle=  document.head.querySelector(`style[id='${sourceID}']`);
           if(!compStyle){// 没有加载过样式
             //创建新的css
               let newCssList=[];
               for (let rule of ruleList) {
                  let selectorText=rule.selectorText;//css 选择符
                  let oldCss=rule.cssText;
                  let newCss= oldCss.replace(selectorText,`${selectorText}[${sourceID}]`);//替换选择符
                  //console.log(newCss);
                  newCssList.push(newCss);
               }
              //动态创建style
              let styleElement = document.createElement("style");
              styleElement.type = "text/css";  
              styleElement.id=sourceID;
              try{
                 styleElement.appendChild(document.createTextNode(newCssList.join(" ")));
              }catch(ex){
                 styleElement.styleSheet.cssText = newCssList.join(" ");//针对IE
              }
              document.head.appendChild(styleElement);
          }
           
           //获取  template 的所有子节点 children
           //选择所有子节点 给所有节点添加动态属性
           let children= template.content.querySelectorAll('*') ;
           children.forEach(function(e) {
               e.setAttribute(sourceID,'');//动态添加属性
           });
           module.default.template = template;
           vueConfig = module.default;
           //原始方法 利用web组件
           //registerComponent({defaultOptions: module.default, template, style});
           //let html =`<${compId}></${compId}>`;
           //config = {template: html};
        }else{// 非 scoped
          // 查询是否已经加载过样式
          let compStyle=  document.head.querySelector(`style[id='${sourceID}']`);
          if(!compStyle){// 没有加载过样式
             style.id=sourceID;
             document.head.appendChild(style);
          }
          module.default.template = template;
          vueConfig = module.default;
        }
    } else {
        module.default.template = template;
        vueConfig = module.default;
    }
    return vueConfig;
}

async function loadAndSetting(url, customOptions) {
    let options = await loadAndParse(url, customOptions);
    let vueConfig  = await getSettings({...options});
    return vueConfig;
}


// 异步加载
function vload(url, customOptions) {
    return  ()=> {
        customOptions = customOptions || {};
        return loadAndSetting(url, customOptions);
    }
}

// 全局组件
//function vtag(tagName, url, customOptions) {
//    return Vue.component(tagName,  vload(url, customOptions));
//}


exports.vload = vload;
exports.config = config;

return exports;

}({}));

